#!/usr/bin/env python
# _*_coding:utf-8_*_

"""
@Time :    2019/9/21 15:19
@Author:  ThinHeader
@File: lib.py
@Software: PyCharm
"""
import hashlib
import json
import random
import string
import threading
import time
import urllib
from urllib import parse
from urllib.request import urlopen

import requests
from rest_framework.test import RequestsClient
import xml.etree.ElementTree as ET

from common.tools.money_cast import transforms_int
from common.tools.ucpaas import UnPaacConfig
from common.wx.config import WxPayConf_pub, WxPayConf_service, WxPayConf_shop

try:
    import pycurl
    from cStringIO import StringIO
except ImportError:
    pycurl = None


class BaseHttpClient(object):
    include_ssl = False

    def get(self, url, second=30):
        if self.include_ssl:
            return self.postXmlSSL(None, url, second, False, post=False)
        else:
            return self.postXml(None, url, second)

    def postXml(self, xml, url, second=30):
        if self.include_ssl:
            return self.postXmlSSL(xml, url, second, cert=False)
        else:
            raise NotImplementedError("please implement postXML")

    def postXmlSSL(self, xml, url, second=30, cert=True, cert_path=WxPayConf_pub.SSLCERT_PATH,
                   key_path=WxPayConf_pub.SSLKEY_PATH, post=True):
        raise NotImplementedError("please implement postXMLSSL")


class Singleton(object):
    """可配置单例模式"""

    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with cls._instance_lock:
                if not hasattr(cls, "_instance"):
                    impl = cls.configure() if hasattr(cls, "configure") else cls
                    instance = super(Singleton, cls).__new__(impl, *args, **kwargs)
                    if not isinstance(instance, cls):
                        instance.__init__(*args, **kwargs)
                    cls._instance = instance
        return cls._instance


class UrllibClient(BaseHttpClient):
    """使用urlib2发送请求"""

    def postXml(self, xml, url, second=30):
        """不使用证书"""
        if xml:
            xml = xml.encode('utf8')
        data = urlopen(url, xml, timeout=second).read()
        return data


class CurlClient(BaseHttpClient):
    """使用Curl发送请求"""
    include_ssl = True

    def __init__(self):
        self.curl = pycurl.Curl()
        self.curl.setopt(pycurl.SSL_VERIFYHOST, False)
        self.curl.setopt(pycurl.SSL_VERIFYPEER, False)
        # 设置不输出header
        self.curl.setopt(pycurl.HEADER, False)

    def postXmlSSL(self, xml, url, second=30, cert=True, cert_path=WxPayConf_pub.SSLCERT_PATH,
                   key_path=WxPayConf_pub.SSLKEY_PATH, post=True):
        """使用证书"""
        self.curl.setopt(pycurl.URL, url)
        self.curl.setopt(pycurl.TIMEOUT, second)
        # 设置证书
        # 使用证书：cert 与 key 分别属于两个.pem文件
        # 默认格式为PEM，可以注释
        if cert:
            self.curl.setopt(pycurl.SSLKEYTYPE, "PEM")
            self.curl.setopt(pycurl.SSLKEY, key_path)
            self.curl.setopt(pycurl.SSLCERTTYPE, "PEM")
            self.curl.setopt(pycurl.SSLCERT, cert_path)
        # post提交方式
        if post:
            self.curl.setopt(pycurl.POST, True)
            self.curl.setopt(pycurl.POSTFIELDS, xml)
        buff = StringIO()
        self.curl.setopt(pycurl.WRITEFUNCTION, buff.write)

        self.curl.perform()
        return buff.getvalue()


class HttpClient(Singleton, BaseHttpClient):

    @classmethod
    def configure(cls):
        config_client = WxPayConf_pub.HTTP_CLIENT
        client_cls = {"urllib": UrllibClient,
                      "curl": CurlClient,
                      "requests": RequestsClient}.get(config_client.lower(), None)
        if client_cls:
            return client_cls

        if pycurl is not None:
            print("HTTP_CLIENT config error, Use 'CURL'")
            return CurlClient
        if requests is not None:
            print("HTTP_CLIENT config error, Use 'REQUESTS'")
            return RequestsClient
        else:
            print("HTTP_CLIENT config error, Use 'URLLIB'")
            return UrllibClient

    def postXml(self, xml, url, second=30):
        """不使用证书"""
        data = urlopen(url, xml, timeout=second).read()
        return data


class WeixinHelper(object):
    @classmethod
    def checkSignature(cls, signature, timestamp, nonce):
        """微信对接签名校验"""
        tmp = [WxPayConf_pub.TOKEN, timestamp, nonce]
        tmp.sort()
        code = hashlib.sha1("".join(tmp).encode('utf8')).hexdigest()
        return code == signature

    @classmethod
    def nonceStr(cls, length):
        """随机数"""
        return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

    @classmethod
    def xmlToArray(cls, xml):
        """将xml转为array"""
        return dict((child.tag, child.text) for child in ET.fromstring(xml))

    @classmethod
    def oauth2(cls, redirect_uri, scope="snsapi_userinfo", state="STATE"):
        """网页授权获取用户信息
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}&connect_redirect=1#wechat_redirect"
        return _OAUTH_URL.format(WxPayConf_pub.APPID, parse.quote(redirect_uri, safe=''), scope, state)

    @classmethod
    def oauth2_service(cls, redirect_uri, scope="snsapi_userinfo", state="STATE"):
        """网页授权获取用户信息
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}&connect_redirect=1#wechat_redirect"
        return _OAUTH_URL.format(WxPayConf_service.APPID, parse.quote(redirect_uri, safe=''), scope, state)

    @classmethod
    def proxy(cls, redirect_uri, scope="snsapi_userinfo", state="STATE", device="mobile"):
        """网页授权获取用户信息
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _PROXY_URL = "http://shop.xuemei99.com/open/proxy?redirect_uri={0}&scope={1}&state={2}&device={3}"
        return _PROXY_URL.format(parse.quote(redirect_uri, safe=''), scope, state, device)

    @classmethod
    def proxy_service(cls, redirect_uri, scope="snsapi_userinfo", state="STATE", device="mobile"):
        """网页授权获取用户信息
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _PROXY_URL = "http://show.xuemei99.com/open/proxy/service?redirect_uri={0}&scope={1}&state={2}&device={3}"
        return _PROXY_URL.format(parse.quote(redirect_uri, safe=''), scope, state, device)

    @classmethod
    def getAccessToken(cls, appid=WxPayConf_pub.APPID, secret=WxPayConf_pub.APPSECRET):
        """获取access_token
        需要缓存access_token,由于缓存方式各种各样，不在此提供
        http://mp.weixin.qq.com/wiki/11/0e4b294685f817b95cbed85ba5e82b8f.html
        """
        _ACCESS_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"
        return UrllibClient().get(_ACCESS_URL.format(appid, secret))

    @classmethod
    def getUserInfo(cls, access_token, openid, lang="zh_CN"):
        """获取用户基本信息
        http://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html
        """
        _USER_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}"
        return UrllibClient().get(_USER_URL.format(access_token, openid, lang))

    @classmethod
    def getUserInfoBatch(cls, data, access_token):
        """批量获取用户基本信息
        http://mp.weixin.qq.com/wiki/1/8a5ce6257f1d3b2afb20f83e72b72ce9.html
        """
        _USER_URL = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={0}"
        return UrllibClient().postXml(data, _USER_URL.format(access_token))

    @classmethod
    def getAccessTokenByCode(cls, code):
        """通过code换取网页授权access_token, 该access_token与getAccessToken()返回是不一样的
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _CODEACCESS_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code"
        url = _CODEACCESS_URL.format(WxPayConf_shop.APPID, WxPayConf_shop.APPSECRET, code)
        return UrllibClient().get(url)

    @classmethod
    def getServiceAccessTokenByCode(cls, code):
        """通过code换取网页授权access_token, 该access_token与getAccessToken()返回是不一样的
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _CODEACCESS_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code"
        url = _CODEACCESS_URL.format(WxPayConf_service.APPID, WxPayConf_service.APPSECRET, code)
        return UrllibClient().get(url)

    @classmethod
    def refreshAccessToken(cls, refresh_token):
        """刷新access_token, 使用getAccessTokenByCode()返回的refresh_token刷新access_token，可获得较长时间有效期
        http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
        """
        _REFRESHTOKRN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type=refresh_token&refresh_token={1}"
        return UrllibClient().get(_REFRESHTOKRN_URL.format(WxPayConf_pub.APPID, refresh_token))

    @classmethod
    def getSnsapiUserInfo(cls, access_token, openid, lang="zh_CN"):
        """拉取用户信息(通过网页授权)
        """
        _SNSUSER_URL = "https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang={2}"
        return UrllibClient().get(_SNSUSER_URL.format(access_token, openid, lang))

    @classmethod
    def getAccessTokenValid(cls, access_token, openid):
        """检测access_token是否过期"""
        _ACCESSTOKEN_VALID_URL = 'https://api.weixin.qq.com/sns/auth?access_token={0}&openid={1}'
        return UrllibClient().get(_ACCESSTOKEN_VALID_URL.format(access_token, openid))

    @classmethod
    def getMaterialList(cls, data, access_token):
        """发送客服消息
        http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
        """
        _SEND_URL = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={0}"
        data = json.dumps(data, ensure_ascii=False)
        return UrllibClient().postXml(data, _SEND_URL.format(access_token))

    @classmethod
    def sendMsgAll(cls, data, access_token):
        """发送客服消息
        http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
        """
        _SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}"
        data = json.dumps(data, ensure_ascii=False)
        return UrllibClient().postXml(data, _SEND_URL.format(access_token))

    @classmethod
    def send(cls, data, access_token):
        """发送客服消息
        http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
        """
        _SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}"
        data = json.dumps(data, ensure_ascii=False)
        return UrllibClient().postXml(data, _SEND_URL.format(access_token))

    @classmethod
    def sendTemplateMsg(cls, data, access_token):
        """发送模版消息
        http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
        """
        _SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}"
        data = json.dumps(data, ensure_ascii=False)
        return UrllibClient().postXml(data, _SEND_URL.format(access_token))

    @classmethod
    def getTextMessage(cls, openid, message):
        data = {
            "touser": openid,
            "msgtype": "text",
            "text":
                {
                    "content": message
                }
        }
        return data

    @classmethod
    def sendTextMessage(cls, openid, message, access_token):
        """发送文本消息
        """
        data = {
            "touser": openid,
            "msgtype": "text",
            "text":
                {
                    "content": message
                }
        }
        return cls.send(data, access_token)

    @classmethod
    def getJsapiTicket(cls, access_token):
        """获取jsapi_tocket
        """
        _JSAPI_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi"
        return UrllibClient().get(_JSAPI_URL.format(access_token))

    @classmethod
    def jsapiSign(cls, jsapi_ticket, url):
        """jsapi_ticket 签名"""
        sign = {
            'nonceStr': cls.nonceStr(15),
            'jsapi_ticket': jsapi_ticket,
            'timestamp': int(time.time()),
            'url': url
        }
        signature = '&'.join(['%s=%s' % (key.lower(), sign[key]) for key in sorted(sign)])
        sign["signature"] = hashlib.sha1(signature.encode('utf8')).hexdigest()
        return sign

    @classmethod
    def long2short(cls, long_url, access_token):
        """长链接转短链接
        https://mp.weixin.qq.com/wiki/6/856aaeb492026466277ea39233dc23ee.html
        """
        _SEND_URL = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token={0}"
        data = json.dumps({'long_url': long_url, 'action': 'long2short'}, ensure_ascii=False)
        return UrllibClient().postXml(data, _SEND_URL.format(access_token))

    @classmethod
    def getComponentAccessToken(cls, app_id, app_secret, ticket):
        """开放平台--获取component access token"""
        _COMPONENT_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"
        data = json.dumps(
            {'component_appid': app_id, 'component_appsecret': app_secret, 'component_verify_ticket': ticket},
            ensure_ascii=False)
        return UrllibClient().postXml(data, _COMPONENT_URL)

    @classmethod
    def getPreAuthCode(cls, app_id, component_access_token):
        """开放平台--获取预授权码"""
        _PRE_AUTH_CODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={0}"
        data = json.dumps({'component_appid': app_id}, ensure_ascii=False)
        return UrllibClient().postXml(data, _PRE_AUTH_CODE_URL.format(component_access_token))

    @classmethod
    def getQueryAuth(cls, app_id, code, component_access_token):
        """开放平台--使用授权码换取公众号的接口调用凭据和授权信息"""
        _QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={0}"
        data = json.dumps({'component_appid': app_id, 'authorization_code': code}, ensure_ascii=False)
        return UrllibClient().postXml(data, _QUERY_AUTH_URL.format(component_access_token))

    @classmethod
    def getAuthorizerToken(cls, component_access_token, component_appid, authorizer_appid, authorizer_refresh_token):
        """开放平台--获取公众号接口调用token"""
        _AUTH_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token={0}"
        data = json.dumps({'component_appid': component_appid, 'authorizer_appid': authorizer_appid,
                           'authorizer_refresh_token': authorizer_refresh_token}, ensure_ascii=False)
        return UrllibClient().postXml(data, _AUTH_TOKEN_URL.format(component_access_token))

    @classmethod
    def getAuthInfo(cls, app_id, auth_app_id, component_access_token):
        """开放平台--获取授权方的公众号帐号基本信息"""
        _AUTH_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token={0}"
        data = json.dumps({'component_appid': app_id, 'authorizer_appid': auth_app_id}, ensure_ascii=False)
        return UrllibClient().postXml(data, _AUTH_INFO_URL.format(component_access_token))

    @classmethod
    def openOauth2(cls, app_id, c_app_id, redirect_uri, scope="snsapi_userinfo", state="STATE"):
        """开放平台--网页授权获取code
        https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318590&token=&lang=zh_CN
        """
        _OPEN_OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}&component_appid={4}#wechat_redirect"
        return _OPEN_OAUTH_URL.format(app_id, parse.quote(redirect_uri, safe=''), scope, state, c_app_id)

    @classmethod
    def openGetAccessToken(cls, app_id, code, c_app_id, token):
        """开放平台--网页授权获取code
        https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318590&token=&lang=zh_CN
        """
        _OPEN_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid={0}&code={1}&grant_type=authorization_code&component_appid={2}&component_access_token={3}"
        return UrllibClient().get(_OPEN_TOKEN_URL.format(app_id, code, c_app_id, token))

    @classmethod
    def openRefreshAccessToken(cls, app_id, c_app_id, c_access_token, refresh_token):
        """开放平台--网页授权获取code
        https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318590&token=&lang=zh_CN
        """
        _OPEN_REFRESH_URL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid={0}&grant_type=refresh_token&component_appid={1}&component_access_token={2}&refresh_token={3}"
        return UrllibClient().get(_OPEN_REFRESH_URL.format(app_id, c_app_id, c_access_token, refresh_token))

    @classmethod
    def postXcxCreateOpenApi(cls, access_token, appid):
        """
        第二步 小程序创建绑定公众开放平台的api
        """
        _XCX_BIND_OPEN_URL = "https://api.weixin.qq.com/cgi-bin/open/create?access_token={0}"
        data = json.dumps({'appid': appid}, ensure_ascii=False)
        return UrllibClient().postXml(data, _XCX_BIND_OPEN_URL.format(access_token))

    @classmethod
    def postXcxBindOpen(cls, access_token, appid, open_appid):
        """
        第二步 小程序绑定公众开发平台
        """
        _XCX_BIND_OPEN_URL = "https://api.weixin.qq.com/cgi-bin/open/bind?access_token={0}"
        data = json.dumps({'appid': appid, 'open_appid': open_appid}, ensure_ascii=False)
        return UrllibClient().postXml(data, _XCX_BIND_OPEN_URL.format(access_token))

    @classmethod
    def postXcxBindInfo(cls, access_token, appid):
        """
        第二步  获取公众号/小程序所绑定的开放平台帐号
        """
        _XCX_BIND_OPEN_URL = "https://api.weixin.qq.com/cgi-bin/open/get?access_token={0}"
        data = json.dumps({'appid': appid}, ensure_ascii=False)
        return UrllibClient().postXml(data, _XCX_BIND_OPEN_URL.format(access_token))

    @classmethod
    def postReleaseCode(cls, access_token):
        """
        第六步  发布已通过审核的小程序（仅供第三方代小程序调用）
        """
        _SET_CODE_URL = "https://api.weixin.qq.com/wxa/release?access_token={0}"
        data = json.dumps({}, ensure_ascii=False)
        return UrllibClient().postXml(data, _SET_CODE_URL.format(access_token))

    @classmethod
    def getHomeQrCode(cls, width, access_token, shop='123'):
        """
        可生成首页小程序二维码
        """
        _QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}"
        data = json.dumps({'width': width, 'page': 'pages/homePage/homePage', 'scene': shop}, ensure_ascii=False)
        return UrllibClient().postXml(data, _QR_CODE_URL.format(access_token))

    @classmethod
    def getAddressPosition(cls, key, address, city):
        """
        获取高德地图的经纬度
        """
        _ADDRESS_POSITION_URL = "http://restapi.amap.com/v3/geocode/geo?key={0}&address={1}&city={2}"
        url = _ADDRESS_POSITION_URL.format(key, address.encode('utf8'), city.encode('utf8'))
        return UrllibClient().get(url)

    @classmethod
    def getQrCode(cls, path, scene, width, access_token):
        """
        第七步  生成二维码 可生成小程序二维码
        """
        _QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}"
        data = json.dumps({'page': path, 'scene': scene, 'width': width}, ensure_ascii=False)
        return UrllibClient().postXml(data, _QR_CODE_URL.format(access_token))

    @classmethod
    def setIndustry(cls, access_token, industry_id1, industry_id2):
        """
        模版消息，设置所属行业
        """
        _SET_INDUSTRY_URL = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token={0}"
        data = json.dumps({'industry_id1': industry_id1, 'industry_id2': industry_id2}, ensure_ascii=False)
        return UrllibClient().postXml(data, _SET_INDUSTRY_URL.format(access_token))

    @classmethod
    def getIndustry(cls, access_token):
        """
        模版消息，获得所属行业
        """
        _GET_INDUSTRY_URL = "https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token={0}"
        return UrllibClient().get(_GET_INDUSTRY_URL.format(access_token))

    @classmethod
    def addTemplate(cls, access_token, template_id_short):
        """模版消息，设置模版"""
        _ADD_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={0}"
        data = json.dumps({'template_id_short': template_id_short}, ensure_ascii=False)
        return UrllibClient().postXml(data, _ADD_TEMPLATE_URL.format(access_token))

    @classmethod
    def getTemplate(cls, access_token):
        """模版消息，设置模版"""
        _GET_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token={0}"
        return UrllibClient().get(_GET_TEMPLATE_URL.format(access_token))

    @classmethod
    def postBindCode(cls, access_token, template_id, user_version, user_desc, ext_json):
        """
        第一步  上传代码--接口--特约商户
        """
        _SET_CODE_URL = "https://api.weixin.qq.com/wxa/commit?access_token={0}"
        data = json.dumps(
            {'template_id': template_id, 'user_version': user_version.encode('utf8'),
             'user_desc': user_desc.encode('utf8'), 'ext_json': ext_json.encode('utf8')},
            ensure_ascii=False)
        return UrllibClient().postXml(data, _SET_CODE_URL.format(access_token))

    @classmethod
    def getCategory(cls, access_token):
        """
        开放平台--获取授权小程序帐号的可选类目
        """
        _SET_TEST_QRCODE_URL = "https://api.weixin.qq.com/wxa/get_category?access_token={0}"
        return UrllibClient().get(_SET_TEST_QRCODE_URL.format(access_token))

    @classmethod
    def postXcxCommitCode(cls, access_token, category_list):
        """
        第四步  特约用户小程序提交代码审核
        """

        _XCX_COMMIT_CODE_URL = " https://api.weixin.qq.com/wxa/submit_audit?access_token={0}"

        category = category_list[0]
        first_class = category['first_class']
        first_id = category['first_id']
        first_id = transforms_int(first_id)
        second_class = category['second_class']
        second_id = category['second_id']
        second_id = transforms_int(second_id)
        data2 = {
            "item_list": [
                {"address": "pages/home/homePage", "tag": "card",
                 "first_class": first_class.encode('utf8'),
                 "second_class": second_class.encode('utf8'), "first_id": first_id, "second_id": second_id,
                 "title": "店家".encode('utf8')},
                {"address": "pages/recruit/recruitHomePage", "tag": "product",
                 "first_class": first_class.encode('utf8'), "second_class": second_class.encode('utf8'),
                 "first_id": first_id, "second_id": second_id, "title": "招募".encode('utf8')},
                {"address": "pages/message/messageList", "tag": "product",
                 "first_class": first_class.encode('utf8'), "second_class": second_class.encode('utf8'),
                 "first_id": first_id, "second_id": second_id, "title": "消息".encode('utf8')},
                {"address": "pages/personalCenter/personalCenter", "tag": "news",
                 "first_class": first_class.encode('utf8'), "second_class": second_class.encode('utf8'),
                 "first_id": first_id, "second_id": second_id,
                 "title": "我的店铺".encode('utf8')}]}

        data = json.dumps(data2, ensure_ascii=False)

        return UrllibClient().postXml(data, _XCX_COMMIT_CODE_URL.format(access_token))

    @classmethod
    def getExamine(cls, access_token):
        """
        第五步  特约用户小程序获取最新的审核结果
        """
        _SET_EXAMINE_URL = "https://api.weixin.qq.com/wxa/get_latest_auditstatus?access_token={0}"
        return UrllibClient().get(_SET_EXAMINE_URL.format(access_token))

    @classmethod
    def getTemplist(cls, access_token):
        """
        1、获取草稿箱内的所有临时代码草稿
        """
        _SET_DRAFT_LIST_URL = "https://api.weixin.qq.com/wxa/gettemplatelist?access_token={0}"
        return UrllibClient().get(_SET_DRAFT_LIST_URL.format(access_token))

    # 微信用户数据分析l
    # 文档地址 https://developers.weixin.qq.com/miniprogram/dev/api/analysis-visit.html

    @classmethod
    def get_analysis_day(cls, access_token, date):
        """微信访问日趋势分析数据"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": date, "end_date": date})

    @classmethod
    def get_analysis_week(cls, access_token, begin_date, end_date):
        """微信访问周趋势分析数据"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": begin_date, "end_date": end_date})

    @classmethod
    def get_analysis_month(cls, access_token, begin_date, end_date):
        """微信访问月趋势分析数据"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": begin_date, "end_date": end_date})

    @classmethod
    def get_access_distribution_day(cls, access_token, date):
        """微信访问日分布"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": date, "end_date": date})

    @classmethod
    def get_access_distribution_week(cls, access_token, begin_date, end_date):
        """微信访问周分布"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": begin_date, "end_date": end_date})

    @classmethod
    def get_access_distribution_month(cls, access_token, begin_date, end_date):
        """微信访问月分布"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo?access_token={}". \
            format(access_token)
        return requests.post(__URL, json={"begin_date": begin_date, "end_date": end_date})

    @classmethod
    def get_analysis_access_page(cls, access_token, date):
        """访问页面"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage?access_token={}".format(access_token)
        return requests.post(__URL, json={"begin_date": date, "end_date": date})

    @classmethod
    def get_user_portrait(cls, access_token, begin_date, end_date):
        """用户画像"""
        __URL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait?access_token={}".format(access_token)
        return requests.post(__URL, json={"begin_date": begin_date, "end_date": end_date})

    @classmethod
    def post_send_message(cls, phone, code):
        """发送验证码"""
        # 380037 默认为模版的id 在云之迅后台进行了设置
        __URL = "https://open.ucpaas.com/ol/sms/sendsms"
        param = "%s, %s" % (code, "5")
        message = requests.post(__URL, json={"sid": UnPaacConfig.AccountSid, "token": UnPaacConfig.AuthToken,
                                             "appid": UnPaacConfig.AppID,
                                             "templateid": "503491", "param": param, "mobile": phone})
        message = json.loads(message)
        if message['code'] == 0:
            return True
        else:
            return False

    @classmethod
    def postHttpUrl(cls, access_token, action):
        """
        第三步 小程序的公众号设置url
        """
        _SET_URL_URL = "https://api.weixin.qq.com/wxa/modify_domain?access_token={0}"
        data = json.dumps({
            'requestdomain': ['wx.extend.xuemei99.com', 'xcx.xuemei99.com', 'show.xuemei99.com',
                              'show.qnssl.xuemei99.com', 'wx.show.xuemei99.com', 'restapi.amap.com'],
            # 'wsrequestdomain':['wss://www.qq.com','wss://www.qq.com'],
            'uploaddomain': ['image.show.xuemei99.com', 'image.xuemei99.com', 'show.qnssl.xuemei99.com',
                             'wx.extend.xuemei99.com',
                             'xcx.xuemei99.com', 'extend.qnssl.xuemei99.com',
                             'music.qnssl.xuemei99.com', 'wx.qlogo.cn', 'thirdwx.qlogo.cn'],
            'downloaddomain': ['image.show.xuemei99.com', 'image.xuemei99.com', 'show.qnssl.xuemei99.com',
                               'wx.extend.xuemei99.com',
                               'extend.qnssl.xuemei99.com',
                               'music.qnssl.xuemei99.com', 'wx.qlogo.cn', 'thirdwx.qlogo.cn'],
            'action': action}, ensure_ascii=False)
        return UrllibClient().postXml(data, _SET_URL_URL.format(access_token))

    @classmethod
    def postHttpExtendUrl(cls, access_token, action):
        """
        第三步 小程序的公众号设置url
        """
        _SET_URL_URL = "https://api.weixin.qq.com/wxa/modify_domain?access_token={0}"
        data = json.dumps({
            "requestdomain": ["wx.extend.xuemei99.com", "www.xuemei99.com"],
            "uploaddomain": ["extend.qnssl.xuemei99.com", "music.qnssl.xuemei99.com", "wx.extend.xuemei99.com"],
            "downloaddomain": ["extend.qnssl.xuemei99.com"], "action": action}, ensure_ascii=False)
        return UrllibClient().postXml(data, _SET_URL_URL.format(access_token))
